#include "GLSamplerState.h"

namespace Rz { namespace Graphics { namespace Render { namespace Libraries { namespace OpenGL {

GLSamplerState::GLSamplerState(IRenderDevice* renderDevice)
	: _handle(0)
	, _isDirty(true)
{
	this->SetRenderDevice(renderDevice);

	_handle = GL::GenSampler();
}

GLSamplerState::~GLSamplerState()
{
	GL::DeleteSampler(_handle);
}

void GLSamplerState::Bind()
{
	Bind(0);
}

void GLSamplerState::Bind(u32 index)
{
	ISamplerState::Bind(index);
	if (this->IsDirty() && !this->IsBound())
	{
		GL::SamplerParameter(_handle, GL_TEXTURE_WRAP_R, TranslateAddressMode(this->GetAddressU()));
		GL::SamplerParameter(_handle, GL_TEXTURE_WRAP_S, TranslateAddressMode(this->GetAddressV()));
		GL::SamplerParameter(_handle, GL_TEXTURE_WRAP_T, TranslateAddressMode(this->GetAddressW()));

		switch (this->GetFilter())
		{
			default:
			case TextureFilter::Linear:
				GL::SamplerParameter(_handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
				GL::SamplerParameter(_handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				break;

			case TextureFilter::MinLinearMagPointMipLinear:
				GL::SamplerParameter(_handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
				GL::SamplerParameter(_handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				break;
		}
	}

	GL::BindSampler(_handle, index);
}

void GLSamplerState::Unbind()
{
	ISamplerState::Unbind();
}

GLint GLSamplerState::TranslateAddressMode(TextureAddressMode address)
{
	switch (address)
	{
		default:
		case TextureAddressMode::Clamp:		return GL_CLAMP_TO_EDGE;
		case TextureAddressMode::Mirror:	return GL_MIRRORED_REPEAT;
		case TextureAddressMode::Wrap:		return GL_REPEAT;
	}
}

bool GLSamplerState::IsDirty() const
{
	return _isDirty;
}

} } } } }
